using System;
using System.Xml.Serialization;

namespace SharpMud.MudLib.SAMPLE.Environment
{
	/// <summary>
	/// A list of areas
	/// </summary>
	[XmlRoot("AreaList")]
	public class AreaList
	{


		#region Private Variables
		private System.Collections.ArrayList	_Areas;
		private string							_FileName;
		private EnvironmentSystem				_HostEnvironSystem;
		#endregion

		#region Constructors
		public AreaList()
		{
			_Areas = new System.Collections.ArrayList();
		}
		
		public AreaList(string fileName, EnvironmentSystem host)
		{
			_Areas = new System.Collections.ArrayList();
			_FileName = "";
			_HostEnvironSystem = host;
			_FileName = fileName;
		}
		#endregion

		#region Public Properties
		/// <summary>
		/// The AreaListItem's that are in this AreaList
		/// </summary>
		[XmlElement("Area")]
		public AreaListItem[] Areas
		{
			get
			{
				return (AreaListItem[])_Areas.ToArray(typeof(AreaListItem));
			}
			set
			{
				if(value!=null)
				{
					if(value.Length!=0)
					{
						_Areas.AddRange(value);
					}
				}
			}
		}
		/// <summary>
		/// The environment system that this AreaList is a part of
		/// </summary>
		[XmlIgnore()]
		public EnvironmentSystem HostEnvironSystem
		{
			get
			{
				return _HostEnvironSystem;
			}
		}

		/// <summary>
		/// The mud that this AreaList is running on
		/// </summary>
		[XmlIgnore()]
		public MudLib.SAMPLE.MudLibRoot HostMud
		{
			get
			{
				return (MudLib.SAMPLE.MudLibRoot)this.HostEnvironSystem.Host;
			}
		}

		/// <summary>
		/// The filename that this area list was loaded from
		/// </summary>
		[XmlIgnore()]
		public string FileName
		{
			get
			{
				return _FileName;
			}
		}
		#endregion

        private log4net.ILog log
        {
            get
            { return this.HostEnvironSystem.log; }
        }

		#region Public Methods
		/// <summary>
		/// Loads all of the areas that this AreaList represents
		/// </summary>
		public Area[] LoadAllAreas()
		{
			System.Diagnostics.Debug.Assert(this.HostEnvironSystem!=null,"this.HostEnvironSystem!=null");
			System.Diagnostics.Debug.Assert(this._Areas!=null,"this._Areas!=null");
			
			log.Info("Loading AREAs...");
			System.Collections.ArrayList al = new System.Collections.ArrayList();
			foreach(AreaListItem ali in _Areas)
			{
				if(ali==null)
				{
					log.Error("Error! Null AreaListItem found in AreaList.");
					continue;
				}
				if(ali.FileName==null || ali.FileName==String.Empty)
				{
					log.Error("Error! AreaListItem specifies a blank filename!");
					continue;
				}
				log.InfoFormat("Loading Area '{0}'",System.IO.Path.GetFileName(ali.FileName));
				try
				{
					Area a = ali.LoadArea(this.HostEnvironSystem.RootAreasFolder);
					if(a!=null)
					{
						al.Add(a);
					}
					else
					{
						log.Error("Area File '" + System.IO.Path.GetFileName(ali.FileName) + "' loaded as Null!");
					}
				}
				catch(System.IO.FileNotFoundException e)
				{
                    log.Error("ERROR! Loading Area '" + System.IO.Path.GetFileName(ali.FileName) + "', file not found", e);
				}
			}
			log.Info("DONE loading AREAs.");
			if(al.Count==0)
				return new Area[] {};
			else
				return (Area[])al.ToArray(typeof(Area));
		}

		#endregion

		#region Static Stuff
		/// <summary>
		/// This static method loads an area list from the given file. It does not load areas or
		/// initialize them, it just loads the skeleton list.
		/// </summary>
		/// <param name="filename">The file name to load the area list from</param>
		/// <param name="hostEnvironSystem">The environment system that will host the AreaList</param>
		/// <returns>Returns the loaded AreaList</returns>
		public static AreaList LoadAreaList(string filename, EnvironmentSystem hostEnvironSystem)
		{
			AreaList								lal;		
			System.Xml.Serialization.XmlSerializer	xs;
			System.IO.FileStream					fs;
			
//			try
//			{
				xs = new XmlSerializer(typeof(AreaList));
//			}
//			catch(System.Exception e)
//			{
//				return null;
//			}
				
			fs = new System.IO.FileStream(filename,System.IO.FileMode.Open,System.IO.FileAccess.Read);
			lal = (AreaList)xs.Deserialize(fs);
			
			fs.Close();

			lal._HostEnvironSystem = hostEnvironSystem;
			lal._FileName = filename;

			return lal;
		}
		#endregion
	}
}
